package com.bii.gelapp;

import java.util.ArrayList;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.LineChart;
import org.achartengine.chart.PointStyle;
import org.achartengine.chart.ScatterChart;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class ScatterGraph {
	
	public Menu menu;
	String graphOrigin;
	
	public static double formulaA;
	public static double formulaB;
	
	public GraphicalView getGraphicalView(Context context, double[] distance,
			double[] gelvalues, double[] componentdistance, String origin) {
		
		final Context ccontext = context;
		final double[] x = distance;
		final double[] values = gelvalues;
		final double[] cdistance = componentdistance;
		graphOrigin = origin;

		double[] cvalue = new double[cdistance.length];

		XYSeries series = new XYSeries("Markers");
		for (int k = 0; k < x.length; k++) {
			series.add(x[k], values[k]);
		}

		// formula of line
		double m1 = 0;
		double m2 = 0;
		double m3 = 0;
		double m4 = 0;
		for (int i = 0; i < distance.length; i++) {
			double dst = distance[i];
			m1 += dst * dst;
			m2 += distance[i] * values[i];
			m3 += distance[i];
			m4 += values[i];
		}

		/*
		 * XMean = SumX / Count
		 * 
		 * YMean = SumY / Count
		 * 
		 * Slope = (SumXY - SumX * YMean) / (SumX2 - SumX * XMean)
		 * 
		 * YInt = YMean - Slope * XMean
		 */

		double XMean = m3 / distance.length;
		double YMean = m4 / distance.length;
		formulaA = (m2 - m3 * YMean) / (m1 - m3 * XMean);
		formulaB = YMean - formulaA * XMean;
		// equation: Y = Slope * X + YInt
		Log.d("tag2", "formulaB: " + formulaB);
		Log.d("tag2", "formulaA: " + formulaA);

		// component drawings
		for (int i = 0; i < cdistance.length; i++) {
			double componentvalue = (formulaA * cdistance[i]) + formulaB;
			cvalue[i] = componentvalue;
			Log.d("tag1",
					"component + " + i + " value: " + Math.pow(10, cvalue[i])
							+ " component distance: " + cdistance[i]);
			
		}
		XYSeries componentseries = new XYSeries("Fragments");
		for (int i = 0; i < cdistance.length; i++) {
			componentseries.add(cdistance[i], cvalue[i]);
		}

		// for values
		for (int i = 0; i < cvalue.length; i++) {
			double valuetoadd = Math.pow(10, cvalue[i]);
			float valueofcomponent = (float) valuetoadd;
			if(origin.equals("Protein")){
				CalculateActivity2.componentvalues.add(valueofcomponent);
			}
			else
			{
				DNACalculateActivity.componentvalues.add(valueofcomponent);
			}
		}

		// best fit line
		double[] bestfity = new double[2];
		double[] bestfitx = new double[2];
		bestfitx[0] = distance[0];
		bestfity[0] = bestfitx[0] * formulaA + formulaB;
		bestfitx[1] = distance[distance.length - 1];
		bestfity[1] = bestfitx[1] * formulaA + formulaB;

		Log.d("tag2", " bestfitx[0]: " + bestfitx[0] + "bestfity[0]: "
				+ bestfity[0] + " bestfitx[1]: " + bestfitx[1]
				+ " bestfity[1]: " + bestfity[1]);

		XYSeries fitlineseries = new XYSeries("Best Fit Line");
		for (int i = 0; i < bestfity.length; i++) {
			fitlineseries.add(bestfitx[i], bestfity[i]);
		}

		// min and max for x and y for limitation on zooming
		double minX = 0;
		for (int i = 0; i < distance.length; i++) {
			if (i == 0) {
				minX = distance[i];
			} else {
				if (distance[i] < minX) {
					minX = distance[i];
				}
			}
		}
		double maxX = 0;
		for (int i = 0; i < distance.length; i++) {
			if (i == 0) {
				maxX = distance[i];
			} else {
				if (distance[i] > maxX) {
					maxX = distance[i];
				}
			}
		}

		double minY = 0;
		for (int i = 0; i < values.length; i++) {
			if (i == 0) {
				minY = values[i];
			} else {
				if (values[i] < minY) {
					minY = values[i];
				}
			}
		}

		double maxY = 0;
		for (int i = 0; i < values.length; i++) {
			if (i == 0) {
				maxY = values[i];
			} else {
				if (distance[i] > maxY) {
					maxY = values[i];
				}
			}
		}

		// adding of series
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		dataset.addSeries(series);
		dataset.addSeries(componentseries);
		dataset.addSeries(fitlineseries);
		// dataset.addSeries(horizontallines);
		// dataset.addSeries(verticallines);

		// for series
		XYSeriesRenderer renderer = new XYSeriesRenderer();
		renderer.setColor(Color.RED);
		renderer.setPointStyle(PointStyle.CIRCLE);
		renderer.setPointStrokeWidth(20);
		renderer.setLineWidth(50);

		// for component series
		XYSeriesRenderer renderer2 = new XYSeriesRenderer();
		renderer2.setColor(Color.BLUE);
		renderer2.setPointStyle(PointStyle.SQUARE);
		renderer2.setPointStrokeWidth(10);
		renderer2.setLineWidth(50);

		// for fitline series
		XYSeriesRenderer renderer3 = new XYSeriesRenderer();
		renderer3.setColor(Color.GREEN);
		renderer3.setPointStyle(PointStyle.POINT);
		renderer3.setPointStrokeWidth(10);
		renderer3.setLineWidth(6);

		XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
		mRenderer.setZoomButtonsVisible(false);
		mRenderer.setZoomEnabled(true, true);
		mRenderer.setPanEnabled(true, true);
		// min and max zoom
		mRenderer.setZoomInLimitX(2);
		mRenderer.setZoomInLimitY(2);
		mRenderer.setShowCustomTextGrid(true);

		// zooming and panning limits
		//double[] panlimits = { 0, maxX + 100, 0, maxY + 2 };
		//double[] zoomlimits = { 0, maxX + 100, 0, maxY + 2 };
		double[]panlimits = {minX - 100, maxX + 100, 0, maxY +1};
		double[]zoomlimits = {minX - 100, maxX + 100, 0, maxY +1};
		mRenderer.setZoomLimits(zoomlimits);
		mRenderer.setPanLimits(panlimits);
		mRenderer.setZoomRate(1.05f);

		mRenderer.setApplyBackgroundColor(true);
		mRenderer.setBackgroundColor(Color.WHITE);
		mRenderer.setMarginsColor(Color.WHITE);

		// adding of renderers
		// series
		mRenderer.addSeriesRenderer(renderer);
		// component
		mRenderer.addSeriesRenderer(renderer2);
		// best fit line
		mRenderer.addSeriesRenderer(renderer3);

		mRenderer.setYLabelsColor(0, Color.BLUE);
		mRenderer.setXLabelsColor(Color.BLUE);
		mRenderer.setLabelsTextSize(30);
		mRenderer.setLegendHeight(50);
		mRenderer.setLegendTextSize(30);
		//mRenderer.setMargins(new int[] { 50, 50, 25, 22 });
		// mRenderer.setLabelsColor(Color.BLUE)];

		// mRenderer.setShowGrid(true);
		// mRenderer.setGridColor(Color.GRAY);
		String[] types = new String[] { ScatterChart.TYPE, ScatterChart.TYPE,
				LineChart.TYPE };
		GraphicalView mChartView = ChartFactory.getCombinedXYChartView(context,
				dataset, mRenderer, types);
		mRenderer.setClickEnabled(true);
		mRenderer.setSelectableBuffer(10);
		mChartView.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// handle the click event on the chart
				ScatterGraph scatter1 = new ScatterGraph();
				Intent lineIntent = scatter1.getIntent(ccontext, x, values,
						cdistance);
				ccontext.startActivity(lineIntent);
			}
		});
		return mChartView;

		// return ChartFactory.getCombinedXYChartView(context, dataset,
		// mRenderer, types);

	}

	public Intent getIntent(Context context, double[] distance,
			double[] gelvalues, double[] componentdistance) {
		double[] x = distance;
		double[] values = gelvalues;
		double[] cdistance = componentdistance;

		double[] cvalue = new double[cdistance.length];

		XYSeries series = new XYSeries("Series 1");
		for (int k = 0; k < x.length; k++) {
			series.add(x[k], values[k]);
		}

		// formula of line
		double m1 = 0;
		double m2 = 0;
		double m3 = 0;
		double m4 = 0;
		for (int i = 0; i < distance.length; i++) {
			double dst = distance[i];
			m1 += dst * dst;
			m2 += distance[i] * values[i];
			m3 += distance[i];
			m4 += values[i];
		}

		/*
		 * XMean = SumX / Count
		 * 
		 * YMean = SumY / Count
		 * 
		 * Slope = (SumXY - SumX * YMean) / (SumX2 - SumX * XMean)
		 * 
		 * YInt = YMean - Slope * XMean
		 */

		double XMean = m3 / distance.length;
		double YMean = m4 / distance.length;
		formulaA = (m2 - m3 * YMean) / (m1 - m3 * XMean);
		formulaB = YMean - formulaA * XMean;
		// equation: Y = Slope * X + YInt
		Log.d("tag2", "formulaB: " + formulaB);
		Log.d("tag2", "formulaA: " + formulaA);

		// component drawings
		for (int i = 0; i < cdistance.length; i++) {
			double componentvalue = (formulaA * cdistance[i]) + formulaB;
			cvalue[i] = componentvalue;

			Log.d("tag1",
					"component + " + i + " value: " + Math.pow(10, cvalue[i])
							+ " component distance: " + cdistance[i]);
		}
		XYSeries componentseries = new XYSeries("component series");
		for (int i = 0; i < cdistance.length; i++) {
			componentseries.add(cdistance[i], cvalue[i]);
		}

		// best fit line
		double[] bestfity = new double[2];
		double[] bestfitx = new double[2];
		bestfitx[0] = distance[0];
		bestfity[0] = bestfitx[0] * formulaA + formulaB;
		bestfitx[1] = distance[distance.length - 1];
		bestfity[1] = bestfitx[1] * formulaA + formulaB;

		Log.d("tag2", " bestfitx[0]: " + bestfitx[0] + "bestfity[0]: "
				+ bestfity[0] + " bestfitx[1]: " + bestfitx[1]
				+ " bestfity[1]: " + bestfity[1]);

		XYSeries fitlineseries = new XYSeries("Best Fit Line");
		for (int i = 0; i < bestfity.length; i++) {
			fitlineseries.add(bestfitx[i], bestfity[i]);
		}

		// min and max for x and y for limitation on zooming
		double minX = 0;
		for (int i = 0; i < distance.length; i++) {
			if (i == 0) {
				minX = distance[i];
			} else {
				if (distance[i] < minX) {
					minX = distance[i];
				}
			}
		}
		double maxX = 0;
		for (int i = 0; i < distance.length; i++) {
			if (i == 0) {
				maxX = distance[i];
			} else {
				if (distance[i] > maxX) {
					maxX = distance[i];
				}
			}
		}

		double minY = 0;
		for (int i = 0; i < values.length; i++) {
			if (i == 0) {
				minY = values[i];
			} else {
				if (values[i] < minY) {
					minY = values[i];
				}
			}
		}

		double maxY = 0;
		for (int i = 0; i < values.length; i++) {
			if (i == 0) {
				maxY = values[i];
			} else {
				if (distance[i] > maxY) {
					maxY = values[i];
				}
			}
		}

		// adding of series
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		dataset.addSeries(series);
		dataset.addSeries(componentseries);
		dataset.addSeries(fitlineseries);
		// dataset.addSeries(horizontallines);
		// dataset.addSeries(verticallines);

		// for series
		XYSeriesRenderer renderer = new XYSeriesRenderer();
		renderer.setColor(Color.RED);
		renderer.setPointStyle(PointStyle.CIRCLE);
		renderer.setPointStrokeWidth(20);
		renderer.setLineWidth(50);

		// for component series
		XYSeriesRenderer renderer2 = new XYSeriesRenderer();
		renderer2.setColor(Color.BLUE);
		renderer2.setPointStyle(PointStyle.SQUARE);
		renderer2.setPointStrokeWidth(10);
		renderer2.setLineWidth(50);

		// for fitline series
		XYSeriesRenderer renderer3 = new XYSeriesRenderer();
		renderer3.setColor(Color.GREEN);
		renderer3.setPointStyle(PointStyle.POINT);
		renderer3.setPointStrokeWidth(10);
		renderer3.setLineWidth(6);

		/*
		 * //for horizontalline series XYSeriesRenderer renderer4 = new
		 * XYSeriesRenderer(); renderer4.setColor(Color.BLUE);
		 * renderer4.setPointStrokeWidth(10); renderer4.setLineWidth(3);
		 * renderer.setStroke(BasicStroke.DASHED);
		 * 
		 * //for verticalline series XYSeriesRenderer renderer5 = new
		 * XYSeriesRenderer(); renderer5.setColor(Color.BLUE);
		 * renderer5.setPointStrokeWidth(10); renderer5.setLineWidth(3);
		 * renderer.setStroke(BasicStroke.DASHED);
		 */

		XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
		mRenderer.setZoomButtonsVisible(false);
		mRenderer.setZoomEnabled(false, true);
		mRenderer.setPanEnabled(true, true);
		// min and max zoom
		mRenderer.setZoomInLimitX(4);
		mRenderer.setZoomInLimitY(2);
		mRenderer.setShowCustomTextGrid(true);

		// zooming and panning limits
		//double[] panlimits = { 0, maxX + 100, 0, maxY + 2 };
		//double[] zoomlimits = { 0, maxX + 100, 0, maxY + 2 };
		double[]panlimits = {minX - 100, maxX + 100, 0, maxY +1};
		double[]zoomlimits = {minX - 100, maxX + 100, 0, maxY +1};
		mRenderer.setZoomLimits(zoomlimits);
		mRenderer.setPanLimits(panlimits);
		mRenderer.setZoomRate(1.05f);

		mRenderer.setApplyBackgroundColor(true);
		mRenderer.setBackgroundColor(Color.WHITE);
		mRenderer.setMarginsColor(Color.WHITE);

		// adding of renderers
		// series
		mRenderer.addSeriesRenderer(renderer);
		// component
		mRenderer.addSeriesRenderer(renderer2);
		// best fit line
		mRenderer.addSeriesRenderer(renderer3);

		mRenderer.setYLabelsColor(0, Color.BLUE);
		mRenderer.setXLabelsColor(Color.BLUE);
		//mRenderer.setLabelsTextSize(30);
		// mRenderer.setLabelsColor(Color.BLUE)];

		// mRenderer.setShowGrid(true);
		// mRenderer.setGridColor(Color.GRAY);
		mRenderer.setLabelsTextSize(50);
		mRenderer.setLegendHeight(50);
		mRenderer.setLegendTextSize(50);
		mRenderer.setMargins(new int[] {50, 50, 100, 50}); //tlbr
		//mRenderer.setMargins(new int[] { 50, 50, 25, 22 });
		

		String[] types = new String[] { ScatterChart.TYPE, ScatterChart.TYPE,
				LineChart.TYPE };
		// return ChartFactory.getCombinedXYChartView(context, dataset,
		// mRenderer, types);
		return ChartFactory.getCombinedXYChartIntent(context, dataset,
				mRenderer, types, "");
	}

	public static double instantCalculate(double distance)
	{
		double componentvalue = (formulaA * distance) + formulaB;
		double valuetoadd = Math.pow(10, componentvalue);
		float valueofcomponent = (float) valuetoadd;
		//float valueofcomponent = (float)componentvalue;
		
		return valueofcomponent;
	}
	
	
	
}	
